'''
Description: 
Author: 
LastEditors: Please set LastEditors
Date: 2023-03-17 14:22:55
LastEditTime: 2023-03-20 14:13:40
'''
from polygon_lou import PolygonIOU

import unittest
import random
import matplotlib.pyplot as plt
from loguru import logger
import numpy as np

import math


class MyTest(unittest.TestCase):
    def setUp(self):
        pass

    def tearDown(self):
        pass

    # 画点
    def __plt_point(self, figure_name: str, point_array: list):
        plt.figure(figure_name)
        x = []
        y = []
        for i in range(len(point_array)):
            x.append(point_array[i][0])
            y.append(point_array[i][1])
            t = str(i+1)
            plt.annotate(t,
                         xy=(point_array[i][0]-.05, point_array[i]
                             [1]+0.15),            # 在(3.3, 0)上做标注
                         fontsize=10,          # 设置字体大小为 16
                         xycoords='data')    # xycoords='data' 是说基于数据的值来选位置
        plt.scatter(x, y)

    # 画线

    def __plt_line(self, figure_name: str, point_array: list, color=None):

        if len(point_array) < 2:
            logger.warning("点的数量小于两个")
            return

        plt.figure(figure_name)
        for i in range(len(point_array)):
            if None == color:
                plt.plot([point_array[i][0], point_array[(i+1) % len(point_array)][0]],
                         [point_array[i][1], point_array[(i+1) % len(point_array)][1]])
            else:
                plt.plot([point_array[i][0], point_array[(i+1) % len(point_array)][0]],
                         [point_array[i][1], point_array[(i+1) % len(point_array)][1]], color)

    # 随机数据

    def __rander_array(self, size=4):
        random_list = []
        for i in range(size):
            x = random.uniform(0, 10)
            y = random.uniform(0, 10)
            random_list.append([x, y])
        return random_list

    def testPoly(self):
        point_array = self.__rander_array(20)

        iou = PolygonIOU()

        # logger.debug(point_array)

        figure_name = '1'
        self.__plt_point(figure_name, point_array)
        self.__plt_line(figure_name, point_array)

        point_array = iou.sort_points(point_array)

        figure_name = '2'
        self.__plt_point(figure_name, point_array)
        self.__plt_line(figure_name, point_array)

        point_array = iou.convex_to_converx(point_array)

        figure_name = '3'
        self.__plt_point(figure_name, point_array)
        self.__plt_line(figure_name, point_array)
        plt.show()

    def testTwoPoly(self):

        # self.asserEqual(PolygonIOU)

        point_array = self.__rander_array(5)
        point_array2 = self.__rander_array(5)
        iou = PolygonIOU()

        # # logger.debug(point_array)

        point_array = iou.sort_points(point_array)
        point_array2 = iou.sort_points(point_array2)

        figure_name = '1'
        self.__plt_point(figure_name, point_array)
        self.__plt_line(figure_name, point_array, "b")

        self.__plt_point(figure_name, point_array2)
        self.__plt_line(figure_name, point_array2, "g")

        point_array = iou.convex_to_converx(point_array)
        point_array2 = iou.convex_to_converx(point_array2)

        figure_name = '2'
        self.__plt_point(figure_name, point_array)
        self.__plt_line(figure_name, point_array, "b")

        self.__plt_point(figure_name, point_array2)
        self.__plt_line(figure_name, point_array2, "g")

        plt.show()

    def testIsInPoly(self):

        # self.asserEqual(PolygonIOU)

        point_array = self.__rander_array(5)
        point_array2 = self.__rander_array(10)

        # point_array = [[2,2], [8,2], [8, 8]]
        # point_array2 = [[5,1]]

        iou = PolygonIOU()

        # # logger.debug(point_array)
        point_array = iou.sort_points(point_array)
        point_array = iou.convex_to_converx(point_array)

        figure_name = '1'
        self.__plt_point(figure_name, point_array)
        self.__plt_line(figure_name, point_array, "b")

        self.__plt_point(figure_name, point_array2)

        for i, p in enumerate(point_array2):

            isIn = iou.is_point_in_polygon(p, point_array)

            if isIn:
                logger.info("point {} in poly", i+1)
            else:
                logger.warning("p {} out", i+1)

        plt.show()

    def testIsLineAcross(self):
        # point_array = self.__rander_array(2)
        # point_array2 = self.__rander_array(2)

        point_array = [[0, 5], [0, -1]]
        point_array2 = [[4, 0], [-1, 0]]

        iou = PolygonIOU()

        figure_name = '1'
        self.__plt_point(figure_name, point_array)
        self.__plt_line(figure_name, point_array, "b")

        self.__plt_point(figure_name, point_array2)
        self.__plt_line(figure_name, point_array2, "g")

        result = iou.is_line_across(point_array[0][0], point_array[0][1], point_array[1][0], point_array[1]
                                    [1], point_array2[0][0], point_array2[0][1], point_array2[1][0], point_array2[1][1])

        if result:
            logger.info("yes")
        else:
            logger.info("no")

        plt.show()

    def testCrossPoint(self):

        point_array = self.__rander_array(2)
        point_array2 = self.__rander_array(2)

        # point_array = [[0,5],[0,-1]]
        # point_array2 = [[4,0],[-1,0]]

        iou = PolygonIOU()

        figure_name = '1'
        self.__plt_point(figure_name, point_array)
        self.__plt_line(figure_name, point_array, "b")

        self.__plt_point(figure_name, point_array2)
        self.__plt_line(figure_name, point_array2, "g")

        result = iou.cross_point(point_array[0][0], point_array[0][1], point_array[1][0], point_array[1]
                                 [1], point_array2[0][0], point_array2[0][1], point_array2[1][0], point_array2[1][1])

        cross_point = [result]

        self.__plt_point(figure_name, cross_point)

        plt.show()

    def testArer(self):

        # point_array = self.__rander_array(50)
        # point_array2 = self.__rander_array(2)

        point_array = [[0, 0], [0, 5], [5, 6], [5, 0], [2.5, 6]]
        # point_array = [[0,0],[0,5],[5,5]]

        iou = PolygonIOU()

        figure_name = '1'

        point_array = iou.sort_points(point_array)
        point_array = iou.convex_to_converx(point_array)

        self.__plt_point(figure_name, point_array)
        self.__plt_line(figure_name, point_array, "b")

        result = iou.polygon_area(point_array)

        logger.info("area={}", result)

        plt.show()

    def test2pArer(self):

        point_array = self.__rander_array(7)
        point_array2 = self.__rander_array(7)

        # point_array = [[0,0],[0,5],[5,6],[5,0],[2.5,6]]
        # point_array2 = [[3,3],[3,5],[5,5]]

        iou = PolygonIOU()

        figure_name = '1'

        point_array = iou.sort_points(point_array)
        point_array = iou.convex_to_converx(point_array)

        self.__plt_point(figure_name, point_array)
        self.__plt_line(figure_name, point_array, "b")

        point_array2 = iou.sort_points(point_array2)
        point_array2 = iou.convex_to_converx(point_array2)

        self.__plt_point(figure_name, point_array2)
        self.__plt_line(figure_name, point_array2, "g")

        result = iou.two_polygon_cross_area(point_array, point_array2)
        self.__plt_line(figure_name, result, "r")

        # logger.info("points={}",result)

        plt.show()

    def testIOU(self):

        point_array = self.__rander_array(5)
        point_array2 = self.__rander_array(5)

        point_array = np.array(point_array)

        iou = PolygonIOU()

        logger.info("iou={}", iou.iou(point_array, point_array2))

        # point_array = [[0,0],[0,5],[5,6],[5,0],[2.5,6]]
        # point_array2 = [[3,3],[3,5],[5,5]]

        figure_name = '1'

        point_array = iou.sort_points(point_array)
        point_array = iou.convex_to_converx(point_array)

        self.__plt_point(figure_name, point_array)
        self.__plt_line(figure_name, point_array, "b")

        point_array2 = iou.sort_points(point_array2)
        point_array2 = iou.convex_to_converx(point_array2)

        self.__plt_point(figure_name, point_array2)
        self.__plt_line(figure_name, point_array2, "g")

        result = iou.two_polygon_cross_area(point_array, point_array2)
        self.__plt_line(figure_name, result, "r")

        plt.show()

    def testRotate(self):

        point_array = self.__rander_array(5)
        point_array = np.array(point_array)

        iou = PolygonIOU()

        figure_name = '1'

        point_array = iou.sort_points(point_array)

        self.__plt_point(figure_name, point_array)
        self.__plt_line(figure_name, point_array, "b")

        # figure_name = '2'
        # point_array = iou.convex_to_converx(point_array)
        p_center = iou.center_point(point_array)

        self.__plt_point(figure_name, [p_center])

        point_array2 = iou.rotate(point_array, p_center, math.pi/2)

        self.__plt_point(figure_name, point_array2)
        self.__plt_line(figure_name, point_array2, "r")

        plt.show()


if __name__ == '__main__':

    logger.add('log_test.txt')

    # 构建测试集
    suite = unittest.TestSuite()
    # suite.addTest(MyTest("testPoly"))

    # suite.addTest(MyTest("testTwoPoly"))

    # suite.addTest(MyTest("testIsInPoly"))

    # suite.addTest(MyTest("testIsLineAcross"))

    # suite.addTest(MyTest("testCrossPoint"))

    # suite.addTest(MyTest("testArer"))

    # suite.addTest(MyTest("test2pArer"))

    suite.addTest(MyTest("testIOU"))
    # suite.addTest(MyTest("testRotate"))

    # 执行
    runner = unittest.TextTestRunner()
    runner.run(suite)

    # unittest.main() #执行全部测试
